import Taro from "@tarojs/taro";
import setting from "./setting";
import requestLoginWrapper from "./authTokenAutoRefresh";
import tokenManager from "./tokenManager";

const StatusErrorMsg = {
  // 请求体内容超出限制
  413: "文件过大",
};

const API_HOST = `${setting.host}${setting.path}`;

// 拦截器
Taro.addInterceptor(function (chain) {
  const requestParams = chain.requestParams;
  const { url } = requestParams;

  return chain.proceed({
    ...requestParams,
    url: API_HOST + url,
  });
});

export type TRequestOptins = {
  // 是否需要token
  tokenAuth?: boolean;
  showErrorToast?: boolean;
};

export type TRequestParams = {
  url: string;
  data?: object;
  method?: "POST" | "GET";
  header?: Record<string, any>;
};

export const request = (params: TRequestParams, options?: TRequestOptins) => {
  const { showErrorToast = true, tokenAuth = true } = options || {};

  return new Promise((resolve, reject) => {
    const header = { ...params.header };
    const token = tokenManager.get();

    if (tokenAuth && token) {
      Reflect.set(header, "Authorization", token);
    }

    Taro.request({
      ...params,
      header,
      success(res) {
        // 服务器响应 && 请求正常
        if (res.statusCode == 200 && res.data.code == 0)
          return resolve(res.data?.data);

        // 接口异常或业务失败
        return reject({
          code: res.statusCode,
          msg: res.data.msg,
          data: res.data,
        });
      },
      fail(error) {
        reject({ code: 400, error });
      },
    });
  }).catch((error) => {
    if (showErrorToast) {
      const title = error.msg || (error.code === 401 ? "请登录" : "请求失败");
      Taro.showToast({ icon: "none", title });
    }

    return Promise.reject({ ...error });
  });
};

// 上传文件
request.upload = (
  url,
  filePath,
  {
    formData,
  }: {
    formData?: Record<string, string | number>;
  } = {}
) => {
  const token = tokenManager.get();

  return Taro.uploadFile({
    name: "file",
    url: API_HOST + url,
    filePath,
    formData,
    header: { Authorization: token },
  })
    .then(({ statusCode, data }) => {
      console.log("Taro.uploadFile:resres", statusCode, data);

      if (statusCode == 200) {
        return JSON.parse(data).data;
      } else {
        return Promise.reject({
          statusCode,
          msg: StatusErrorMsg[413],
        });
      }
    })
    .catch((error) => {
      return Promise.reject({ error });
    });
};

export default (
  requestParams: TRequestParams,
  requeseOptins?: TRequestOptins
) => requestLoginWrapper(request, requestParams, requeseOptins);

export const requestUpload = request.upload;
